﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using Mss.Common.Helpers;
using Mss.Common.Interfaces;

namespace Mss.Managers
{
    public sealed class NavigationManager:NotifyPropertyChangedBase 
    {
        #region Fields

        private readonly Stack<KeyValuePair<Type, IView>> _history;
        private IView _currentView;
        private IView _logOnView;

        #endregion

        #region Singleton Constructor

        private static NavigationManager _instance;

        private NavigationManager()
        {
            _history = new Stack<KeyValuePair<Type, IView>>();

            SecurityManager.Current.CurrentUserChanged += onSecurityCurrentUserChanged;
        }

        public static NavigationManager Current
        {
            get { return _instance ?? (_instance = new NavigationManager()); }
        }

        #endregion

        public IView CurrentView
        {
            get { return _currentView; }
            private set
            {
                if (_currentView == value) return;
                _currentView = value;
                RaisePropertyChanged("CurrentView");
            }
        }

        public void Navigate<T>(T view) where T :class,IView
        {
            if (!view.IsRegistered)
            {
                registerView(view);
            }

            if (CurrentView != null && CurrentView != view)
            {
               // CurrentView.Hide();
            }

            view.Show();
        }

        private void registerView<T>(T view) where T : class,IView
        {
            view.IsRegistered = true;

            view.Showing += onViewShowing;
            view.Closing += onViewClosing;
            view.Hidding += onViewHidding;
        }

        public void RegisterLogOnView<T>(T view) where T :class,IView
        {
            _logOnView = view;
            registerView(view);

            if (SecurityManager.Current.User == null)
            {
                Navigate(_logOnView);
            }
        }

        #region Event Handlers

        private void onSecurityCurrentUserChanged(object sender, EventArgs e)
        {
            if (SecurityManager.Current.User == null)
            {
                Navigate(_logOnView);
            }
            else
            {
                if (CurrentView == _logOnView)
                {
                    _history.Pop();
                    if (_history.Any())
                    {
                        Navigate(_history.Pop().Value);
                    }
                    else
                    {
                        CurrentView = null;
                    }
                }
            }
        }
        
        private void onViewHidding(object sender, EventArgs e)
        {
            //CurrentView = null;
        }

        private void onViewClosing(object sender, EventArgs e)
        {
            CurrentView = null;

            var itemFromHistory = _history.Where(i => i.Key == sender.GetType()).Single();
            itemFromHistory.Value.Dispose();
        }

        private void onViewShowing(object sender, EventArgs e)
        {
            var view = (IView)sender;
            CurrentView = view;

            //Store history.
            var historyRecord = new KeyValuePair<Type, IView>(view.GetType(), view);
            _history.Push(historyRecord);
        } 

        #endregion
    }
}